// requestAnimationFrame 适配函数
const raFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || function (callback) {
  return window.setTimeout(callback, 1000 / 60);
};

/**
 * 判断两个对象是否相等
 * @param {*} object 对象1
 * @param {*} other 对象2
 * @return {boolean}
 */
export function isEqual(object, other) {
  return _isEqual(object, other)
}

/**
 * 节流函数
 * @param {function} fn 事件处理函数
 * @param {object} [context=this] 上下文对象
 * @param {boolean} [isImmediate=false] 是否立刻执行
 * @returns {Function} 事件处理函数
 */
export function throttle(fn, context = this, isImmediate = false) {
  let isLocked;
  return function () {
    const _args = arguments

    if (isLocked) return

    isLocked = true
    raFrame(function () {
      isLocked = false;
      fn.apply(context, _args)
    })

    isImmediate && fn.apply(context, _args)
  }
}


/**
 * 防抖函数
 * @param {function} fn 事件处理函数
 * @param {number} [delay=20] 延迟时间
 * @param {boolean} [isImmediate=false] 是否立刻执行
 * @param {object} [context=this] 上下文对象
 * @returns {Function} 事件处理函数
 */
export function debounce(fn, delay = 20, isImmediate = false, context = this) {
  // 使用闭包，保存执行状态，控制函数调用顺序
  let timer;

  return function () {
    const _args = [].slice.call(arguments)

    clearTimeout(timer);

    const _fn = function () {
      timer = null;
      if (!isImmediate) fn.apply(context, _args);
    };

    // 是否滚动时立刻执行
    const callNow = !timer && isImmediate;

    timer = setTimeout(_fn, delay);

    if (callNow) fn.apply(context, _args);
  }
}

/**
 * 生成随机GUID
 * @return {string}
 */
export function guid() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  }).toUpperCase();
}

/**
 * 生成唯一id
 * @return {string}
 */
export function uid() {
  const rnd = Math.floor(Math.random() * 1000)
  const timestamp = new Date().getTime()
  return [timestamp, rnd].join('')
}

/**
 *金额转换 如：10000.52 转换成 10,000.52
 */
export function numToCurrency(val, digit) {
  val = parseFloat(val);
  if(val === 0 || isNaN(val)){
    return 0;
  }

  if(val.toString().indexOf('.') !== -1) {
    val = val.toFixed(2);
  } else {
    val = val.toString()
  }

  const reg = /(\d{1,3})(?=(\d{3})+(?:$|\D))/g;
  return val.replace(reg,"$1,");
}


/**
 *金额转换 如：10,000.52 转换成 10000.52
 */
export function currencyToNum(val){
  val = '' + val;
  if (val.trim() === '') {
    return 0;
  }
  val = val.replace(/,/g,'');
  val = parseFloat(val);
  return isNaN(val) ? 0 : val;
}

export function toFixed(num) {
  return parseFloat(num.toFixed(2))
}

export function toFixed4(num) {
  return parseFloat(num.toFixed(4))
}

/**
 * 使用正则表达式和函数替换字符串中的变量
 * str = {a} - {b}
 * obj ={
 *   a: 2,
 *   b: 1
 * }
 * 输出: 2 - 1
 * @param str
 * @param obj
 * @returns {*}
 */
export function replaceTemplate(template, data, defaultValue) {
  return template.replace(/{([^{}]*)}/g, function (match, key) {
    return typeof data[key] === 'undefined' ? (typeof defaultValue === 'undefined' ? match : defaultValue)
      : data[key];
  });
}

/**
 * 执行js表达式
 * @param str
 */
export function evalFormula(str) {
  if(!window.IF) {
    window.IF = function(a, b, c) {
      return a ? b : c
    }
  }
  return eval(str)
}

/**
 * 金额转中文大小写
 * @param amount
 * @returns {string}
 */
export function convertToChinese(amount) {
  const cnDigits = "零壹贰叁肆伍陆柒捌玖";
  const cnUnits = ["", "拾", "佰", "仟", "万", "亿"];
  const cnSubUnits = ["角", "分"];

  // 保证金额精确到分
  amount = Math.round(amount * 100) / 100;

  // 分离整数和小数部分
  const integerPart = Math.floor(amount);
  let decimalPart = Math.round((amount - integerPart) * 100);

  // 转换整数部分
  function convertInteger(n) {
    if (n === 0) return "零";
    let parts = [];
    let unitIndex = 0;
    let zeroFlag = false; // 标记是否添加零
    while (n > 0) {
      let digit = n % 10;
      if (digit === 0) {
        if (!zeroFlag && parts.length > 0) {
          parts.push(cnDigits[0]);
          zeroFlag = true;
        }
      } else {
        parts.push(cnDigits[digit] + cnUnits[unitIndex]);
        zeroFlag = false;
      }
      n = Math.floor(n / 10);
      unitIndex++;
    }
    parts.reverse();
    return parts.join('');
  }

  // 转换小数部分
  function convertDecimal(n) {
    if (n === 0) return '';
    let result = [];
    for (let i = 0; i < cnSubUnits.length; i++) {
      let digit = Math.floor(n / Math.pow(10, 1 - i));
      if (digit > 0) {
        result.push(cnDigits[digit] + cnSubUnits[i]);
      }
      n = n % 10;
    }
    return result.join('');
  }

  // 处理整数部分
  let integerCn = convertInteger(integerPart);

  // 处理小数部分
  let decimalCn = convertDecimal(decimalPart);

  // 拼接结果
  if (decimalCn) {
    return integerCn + "元" + decimalCn;
  } else {
    return integerCn + "元整";
  }
}

export function setStorage(storage, key, val) {
  const str = JSON.stringify(val)
  storage.setItem(key, str)
}
export function getStorage(storage, key) {
  const str = storage.getItem(key)
  let val = null
  if(str) {
    try {
      val = JSON.parse(str)
    } catch (e) {
      console.error(e)
    }
  }
  return val
}

export function getLocalStorage(key) {
  return getStorage(localStorage, key)
}

export function setLocalStorage(key, val) {
  setStorage(localStorage, key, val)
}

export function getSessionStorage(key) {
  return getStorage(sessionStorage, key)
}

export function setSessionStorage(key, val) {
  setStorage(sessionStorage, key, val)
}
